﻿// WallpaperApi/Configurations/JwtConfiguration.cs
using Common.Utils;
using Library.Entity;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using System.Text.Json;
using wallpaperApi;

namespace WallpaperApi.Configurations
{
    public static class JwtConfiguration
    {
        public static void ConfigureJwtAuthentication(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    var jwtOpt = configuration.GetSection("JwtOpt").Get<JwtOpt>();
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,
                        ValidIssuer = jwtOpt?.Issuer,
                        ValidAudience = jwtOpt?.Audience,
                        IssuerSigningKey = new SymmetricSecurityKey(
                            Encoding.UTF8.GetBytes(jwtOpt?.SecurityKey ?? "default-key"))
                    };

                    // 添加 JWT 认证事件处理
                    options.Events = new JwtBearerEvents
                    {
                        OnAuthenticationFailed = context =>
                        {
                            var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Program>>();

                            if (context.Response.HasStarted)
                            {
                                logger.LogWarning("响应已开始，跳过认证失败处理");
                                return Task.CompletedTask;
                            }

                            string errorMessage;
                            if (context.Exception is SecurityTokenExpiredException)
                            {
                                errorMessage = "登录状态已过期，请重新登录";
                                logger.LogWarning("JWT Token 已过期");
                            }
                            else
                            {
                                errorMessage = "请先登录";
                                logger.LogWarning("JWT 认证失败: {Error}", context.Exception.Message);
                            }

                            context.Response.StatusCode = 401;
                            context.Response.ContentType = "application/json";
                            var result = JsonSerializer.Serialize(new
                            {
                                isSuccess = false,
                                message = errorMessage,
                                code = 401,
                            });
                            return context.Response.WriteAsync(result);
                        },
                        OnChallenge = context =>
                        {
                            var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Program>>();

                            if (context.Response.HasStarted)
                            {
                                logger.LogWarning("响应已开始，跳过认证挑战处理");
                                return Task.CompletedTask;
                            }

                            logger.LogWarning("JWT 认证挑战: {Error}", context.ErrorDescription);

                            context.Response.StatusCode = 401;
                            context.Response.ContentType = "application/json";

                            var result = JsonSerializer.Serialize(new ApiResponse<Object>
                            {
                                IsSuccess = false,
                                Message = "请先登录",
                                Code = 401
                            });
                            return context.Response.WriteAsync(result);
                        },
                        // 新增 403 处理
                        OnForbidden = context =>
                        {
                            var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Program>>();

                            if (context.Response.HasStarted)
                            {
                                logger.LogWarning("响应已开始，跳过权限不足处理");
                                return Task.CompletedTask;
                            }

                            logger.LogWarning("权限不足，请求被拒绝");

                            context.Response.StatusCode = 403;
                            context.Response.ContentType = "application/json";

                            var result = JsonSerializer.Serialize(new ApiResponse<Object>
                            {
                                IsSuccess = false,
                                Message = "权限不足，请求被拒绝",
                                Code = 403
                            });
                            return context.Response.WriteAsync(result);
                        }
                    };
                });
        }
    }
}